<?php

/**
 *
 * Explain : 逻辑层：公共方法-数据库处理
 * Date    : 2023/07/20 09:32
 */

namespace app\common\Helper;

class FunctionDB
{
    /**
     * 数据库 允许操作字段过滤
     * @param array $fields 允许操作字段
     * @param array $data 请求参数
     * @return array|mixed
     */
    public static function fieldFiltration($fields, $data)
    {
        $result = [];
        if ($fields) {
            foreach ($data as $k => $v) {
                if (in_array($k, $fields)) {
                    $result[$k] = $v;
                }
            }
        } else {
            $result = $data;
        }
        return $result;
    }

    /**
     * 数据库字段属性转换
     * @param array $data
     * @param array $casts 属性转换 ['字段'=>'类型']
     * @param int $isWrite 是否写入数据库；0-否1-是
     * @return mixed
     */
    public static function fieldValCasts($data, $casts, $isWrite = 1)
    {
        if (!$casts || !is_array($casts)) {
            return $data;
        }
        foreach ($casts as $key => $val) {
            // 写入数据库
            if (array_key_exists($key, $data)) {
                if ($isWrite == 1) {
                    // 数组
                    if ($val == 'json' || $val == 'array') {
                        if (!$data[$key]) {
                            $data[$key] = null;
                        } else {
                            if (is_array($data[$key])) {
                                $data[$key] = json_encode($data[$key], JSON_UNESCAPED_UNICODE);
                            }
                        }
                    } elseif ($val == 'integer') {
                        if (is_numeric($data[$key])) {
                            $data[$key] = intval($data[$key]);
                        }
                    }
                } else {
                    // 读取
                    if ($val == 'json' || $val == 'array') {
                        if (!$data[$key]) {
                            $data[$key] = null;
                        } else {
                            if (!is_array($data[$key])) {
                                $data[$key] = json_decode($data[$key], true);
                            }
                        }
                    }

                }
            }
        }
        return $data;
    }

    /**
     * 添加数据字段过滤
     * @param $data
     * @return array
     */
    public static function filedFiltrate($data, $fields, $casts = [])
    {
        if (!is_array($data)) {
            return $data;
        }
        $dataKeys = array_keys($data);
        $fieldsVal = array_values($fields);
        $isOne = false;
        foreach ($dataKeys as $k => $v) {
            if (!is_numeric($v) && in_array($v, $fieldsVal)) {
                $isOne = true;
                break;
            }
        }

        if (count($data) != count($data, 1) && !$isOne) {
            // 二维数组
            $dataNew = [];
            foreach ($data as $key => $val) {
                if (is_array($val)) {
                    // 允许更新字段
                    $val = self::fieldFiltration($fields, $val);
                    // 字段数据转换
                    $val = self::fieldValCasts($val, $casts, 1);
                    $dataNew[$key] = $val;
                }
            }
            $data = $dataNew;
        } else {
            // 数组
            // 允许更新字段
            $data = self::fieldFiltration($fields, $data);
            // 字段数据转换
            $data = self::fieldValCasts($data, $casts, 1);
        }
        return $data;
    }

    /**
     * 补全时间
     * @param string $dateString 日期格式时间
     * @param string $completionString 如果没有HH:ii:ss补全
     * @return mixed|string
     */
    public static function dateTimeCompletion($dateString, $completionString = '00:00:00')
    {
        if (preg_match('/^\d{4}[\-](0?[1-9]|1[012])[\-](0?[1-9]|[12][0-9]|3[01])(\s+(0?[0-9]|1[0-9]|2[0-3])\:(0?[0-9]|[1-5][0-9])\:(0?[0-9]|[1-5][0-9]))$/', $dateString)) {
            return $dateString;
        } else {
            // YYYY-MM-DD
            if (preg_match('/^\d{4}[\-](0?[1-9]|1[012])[\-](0?[1-9]|[12][0-9]|3[01])$/', $dateString)) {
                return $dateString . ' ' . $completionString;
            }
        }
        return $dateString;
    }


    /**
     * 日期格式转时间戳
     * @param string $dateString 日期格式时间
     * @param string $completionString 如果没有HH:ii:ss补全
     * @return float|int|string
     */
    public static function dateToTime($dateString, $completionString = '00:00:00')
    {
        if (!$dateString) {
            return 0;
        }
        if (!is_numeric($dateString)) {
            $dateString = self::dateTimeCompletion($dateString, $completionString);
            $dateString = strtotime($dateString);
        }
        return $dateString;
    }

    /**
     * 精准判断-整数
     * @param array $request 请求参数 ['db_field'=>'值']
     * @param array $preciseIntFiled 精准判断整数字段 ['db_field','db_field']
     * @param array $where 判断条件数组
     * @param array $isNotZeroFiled 不等于0字段
     * @return void
     */
    public static function wherePreciseInteger($request, $preciseIntFiled, &$where = [],$isNotZeroFiled=[])
    {
        if ($preciseIntFiled) {
            foreach ($preciseIntFiled as $k => $v) {
                if (array_key_exists($v, $request) && is_numeric($request[$v])) {
                    if($isNotZeroFiled && in_array($v,$isNotZeroFiled)){
                        if($request[$v] != 0){
                            $where[$v] = $request[$v];
                        }
                    }else{
                        $where[$v] = $request[$v];
                    }
                }
            }
        }
    }

    /**
     * 精准判断-字符串
     * @param array $request 请求参数 ['db_field'=>'值']
     * @param array $preciseStrFiled 精准判断字符串字段 ['db_field','db_field']
     * @param array $where 判断条件数组
     * @return void
     */
    public static function wherePreciseString($request, $preciseStrFiled, &$where = [])
    {
        if ($preciseStrFiled) {
            foreach ($preciseStrFiled as $k => $v) {
                if (isset($request[$v]) && $request[$v]) {
                    $where[$v] = $request[$v];
                }
            }
        }
    }

    /**
     * 判断时间统一格式
     * @param array $request 请求参数 ['db_field'=>['start_time'=>'','end_time'=>'']]
     * @param string $field 数据表时间字段
     * @param string $fieldType 时间字段类型 integer/string
     * @param array $where 判断条件数组
     * @param string $resultType 判断条件内容返回属性 string/array
     * @return void
     */
    public static function whereTime($request, $field, $fieldType = 'integer', &$where = [], $resultType = 'array')
    {
        if (isset($request[$field]) && $request[$field] && is_array($request[$field]) && in_array($fieldType, ['int','integer', 'string'])) {
            $startTime = $request[$field]['start_time'] ?? '';
            $endTime = $request[$field]['end_time'] ?? '';
            if ($fieldType == 'integer') {
                // 时间戳
                $startTime = self::dateToTime($startTime, '00:00:00');
                $endTime = self::dateToTime($endTime, '23:59:59');
            } else {
                // 日期格式
                $startTime = self::dateTimeCompletion($startTime, '00:00:00');
                $endTime = self::dateTimeCompletion($endTime, '23:59:59');
            }

            $whereSql = '';
            $whereArr = [];
            if ($startTime && $endTime) {
                $whereSql = "`{$field}` between {$startTime} and {$endTime}";
                $whereArr = array(array("egt", $startTime), array("elt", $endTime), "and");
            } elseif ($startTime && !$endTime) {
                $whereSql = "`{$field}`>={$startTime}";
                $whereArr = ['egt', $startTime];
            } elseif (!$startTime && $endTime) {
                $whereSql = "`{$field}`<={$endTime}";
                $whereArr = ['elt', $startTime];
            }

            if ($resultType == 'string') {
                if ($whereSql) {
                    $where[] = $whereSql;
                }
            } else {
                if ($whereArr) {
                    $where[$field] = $whereArr;
                }
            }
        }
    }

    /**
     * 字符串为数组情况下转字符串
     * @param $field
     * @return void
     */
    public static function fieldTurnString(&$field)
    {
        if (is_array($field)) {
            $field = implode(',', $field);
        }
    }
}